<template>
  <el-upload v-bind="{ ...elProps }" :http-request="onUpload">
    <template #default>
      <slot name="default"></slot>
    </template>
    <template #trigger>
      <slot name="trigger"></slot>
    </template>
    <template #tip>
      <slot name="tip"></slot>
    </template>
    <template #file>
      <slot name="file"></slot>
    </template>
  </el-upload>
  <!-- <div v-for="file in files" :key="file.id">
    {{ files.length > 1 ? `${file.name}上传进度` : '' }}
    <el-progress v-if="file.percent && showFileList && file.percent !== 100" :percentage="file.percent"></el-progress>
  </div> -->
</template>

<script lang="ts" setup>
/* eslint-disable vue/no-multiple-template-root */
/* eslint-disable @typescript-eslint/no-empty-function */
/* eslint-disable no-undef */
/**
 * 使用方法跟el-upload组件一样
 */
import { withDefaults, defineProps, ref, onMounted, reactive } from 'vue'
import { omit } from 'lodash'
import { ElMessage, UploadRequestOptions, UploadFile } from 'element-plus'
import Upload from '@/common/utils/upload'
import { getUploadUrl } from '@/common/apis/cos'
import { ExtendFile } from '@/common/utils/upload'
import { newDate } from '@/common/utils/common'

interface UploadProps extends Partial<UploadFile> {
  type: any // 上传的types
  scope: string
  limitSize?: string // 例如'20mb'
  onProgress?: (arg: any) => void
  onSuccess?: (file: ExtendFile, files: ExtendFile[]) => void
  onError?: (file: ExtendFile, files: ExtendFile[]) => void
  showFileList?: boolean
}

interface State {
  files: any[]
}

const props = withDefaults(defineProps<UploadProps>(), {
  type: 'common',
  scope: 'common',
  showFileList: true,
  'on-progress': () => {},
  'on-error': () => {},
  'on-success': () => {}
})
// const props: any = defineProps()
const elProps = omit(props, ['type'])
// const { showFileList } = props
const state: State = reactive({
  files: []
})

// const { files } = toRefs(state)

const upload: any = ref(null)

const getFileByte = () => ((props?.limitSize || '').split('mb')[0] as any) * 1024 * 1024

onMounted(() => {
  upload.value = new Upload({
    // isUseQiniu: true,
    fileType: props.type,
    init: {
      /**
       * on-progress，on-success, on-error 三个方法使用自定义的Upload类中的方法
       * 回调参数对象是一样的
       * 其他属性和方法参照element-plus,使用方法不变
       */
      BeforeUpload: onBeforeUpload,
      UploadProgress: onProgress,
      // FileUploaded: props['on-success'] || emptyFn,
      FileUploaded: internalFileUploaded,
      Error: internalError
    }
  })
})

const onBeforeUpload = async (file: ExtendFile) => {
  // console.log(file)
  // console.log(props)
  const key = `${+newDate()}/${file.name}`
  const res = await getUploadUrl({
    key,
    scope: props.scope || 'common'
  })
  file.fileKey = key
  file.putUrl = res.data.url
  file.cosUrl = res.data.cdn
  return file
}

const updateFiles = (file: ExtendFile) => {
  if (state.files.every((i: ExtendFile) => i.uid !== file.uid)) {
    // state.files.push(cloneDeep(file))
    state.files.push(file)
  }
}

const internalError = (_: any, file: ExtendFile) => {
  updateFiles(file)
  props.onError?.(file, state.files)
}

const internalFileUploaded = (_: any, file: ExtendFile) => {
  updateFiles(file)
  props.onSuccess?.(file, state.files)
}

const onProgress = (...arg: any) => {
  // const files = arg[2]
  // console.log(arg, files)
  // state.files = cloneDeep(files)
  if (props['on-progress']) {
    props.onProgress?.(arg)
  }
}

const onUpload = (options: UploadRequestOptions) => {
  const { file } = options
  if (props.limitSize && file.size > getFileByte()) {
    ElMessage.error(`文件大小不能超过${props.limitSize}`)
    return false
  }
  upload.value.files = [file]
  upload.value.start()
  return true
}
</script>
